package com.sdgakj.utils.tencent.common;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sdgakj.utils.tencent.protocol.pay_notify_protocol.PayNotifyReqData;
import com.sdgakj.utils.tencent.protocol.refund_query_protocol.RefundOrderData;

/**
 * User: rizenguo
 * Date: 2014/11/1
 * Time: 14:06
 */
public class XMLParser {

    private static Logger logger = LoggerFactory.getLogger(XMLParser.class);

    /**
     * 从RefunQueryResponseString里面解析出退款订单数据
     * @param refundQueryResponseString RefundQuery API返回的数据
     * @return 因为订单数据有可能是多个，所以返回一个列表
     */
    public static List<RefundOrderData> getRefundOrderList(String refundQueryResponseString) throws IOException, SAXException, ParserConfigurationException {
        List list = new ArrayList();

        Map<String,Object> map = XMLParser.getMapFromXML(refundQueryResponseString);

       int count = Integer.parseInt((String) map.get("refund_count"));
       Util.log("count:" + count);

        if(count<1){
            return list;
        }

        RefundOrderData refundOrderData;

        for(int i=0;i<count;i++){
            refundOrderData = new RefundOrderData();

            refundOrderData.setOutRefundNo(Util.getStringFromMap(map,"out_refund_no_" + i,""));
            refundOrderData.setRefundID(Util.getStringFromMap(map,"refund_id_" + i,""));
            refundOrderData.setRefundChannel(Util.getStringFromMap(map,"refund_channel_" + i,""));
            refundOrderData.setRefundFee(Util.getIntFromMap(map,"refund_fee_" + i));
            refundOrderData.setCouponRefundFee(Util.getIntFromMap(map,"coupon_refund_fee_" + i));
            refundOrderData.setRefundStatus(Util.getStringFromMap(map,"refund_status_" + i,""));
            list.add(refundOrderData);
        }

        return list;
    }

    /**
     * 从unifiedOrderResponseString里面解析统一下订单数据
     * 
     * @param unifiedOrderResponseString UnifiedOrder API返回的数据
     * @return UnifiedOrderResData
     * @throws Exception
     */
    public static Map<String, Object> getUnifiedOrderResData(String unifiedOrderResponseString, String nonceStr)
 throws Exception {
        Map<String, String> map = XMLParser.parseXml(unifiedOrderResponseString);
        String appid = map.get("appid");
        String mch_id = map.get("mch_id");
        String prepay_id = map.get("prepay_id");

        logger.info("return_code:" + map.get("return_code") + ";result_code" + map.get("result_code") + "code_url:"
                + map.get("code_url"));
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("appid", appid);
        resultMap.put("partnerid", mch_id);
        resultMap.put("pacakge", "prepay_id="+prepay_id);
        resultMap.put("noncestr", nonceStr);
        resultMap.put("timestamp", System.currentTimeMillis() / 1000);
        resultMap.put("sign", Signature.getSign(resultMap));
        return resultMap;
    }

    /**
     * 从unifiedOrderResponseString里面解析统一下订单数据
     * 
     * @param unifiedOrderResponseString UnifiedOrder API返回的数据
     * @return UnifiedOrderResData
     * @throws Exception
     */
    public static PayNotifyReqData getPayNotifyResData(String payNotifyResponseString) throws Exception {
        PayNotifyReqData resultResDate = new PayNotifyReqData();
        Map<String, String> map = XMLParser.parseXml(payNotifyResponseString);
        resultResDate.setReturn_code(map.get("return_code"));
        resultResDate.setReturn_msg(map.get("return_msg"));
        resultResDate.setAppid(map.get("appid"));
        resultResDate.setMch_id(map.get("mch_id"));
        resultResDate.setNonce_str(map.get("nonce_str"));
        resultResDate.setSign(map.get("sign"));
        resultResDate.setResult_code(map.get("result_code"));
        resultResDate.setAttach(map.get("attach"));
        resultResDate.setBank_type(map.get("bank_type"));
        resultResDate.setCash_fee(Integer.parseInt(map.get("cash_fee")));
        resultResDate.setCash_fee_type(map.get("cash_fee_type"));
        resultResDate.setCoupon_count(Integer.parseInt(map.get("coupon_count")));
        resultResDate.setCoupon_fee(Integer.parseInt(map.get("coupon_fee")));
        resultResDate.setCoupon_id(map.get("coupon_id"));
        resultResDate.setDevice_info(map.get("device_info"));
        resultResDate.setFee_type(map.get("fee_type"));
        resultResDate.setOpenid(map.get("openid"));
        resultResDate.setOut_trade_no(map.get("out_trade_no"));
        resultResDate.setResult_code(map.get("return_code"));
        resultResDate.setTime_end(map.get("time_end"));
        resultResDate.setTotal_fee(Integer.parseInt(map.get("total_fee")));
        resultResDate.setTransaction_id(map.get("transaction_id"));
        resultResDate.setTrade_type(map.get("trade_type"));

        return resultResDate;
    }

    public static Map<String, Object> getMapFromXML(String xmlString)
            throws ParserConfigurationException, IOException, SAXException {

        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is =  Util.getStringStream(xmlString);
        Document document = builder.parse(is);

        //获取到document里面的全部结点
        NodeList allNodes = document.getFirstChild().getChildNodes();
        Node node;
        Map<String, Object> map = new HashMap<String, Object>();
        int i=0;
        while (i < allNodes.getLength()) {
            node = allNodes.item(i);
            if(node instanceof Element){
                map.put(node.getNodeName(), node.getNodeValue());
            }
            i++;
        }
        return map;

    }

    public static Map<String, String> parseXml(String xmlString) throws Exception {
        // 解析结果存储在HashMap
        Map<String, String> map = new HashMap<String, String>();
        InputStream inputStream = Util.getStringStream(xmlString);
        // 读取输入流
        SAXReader reader = new SAXReader();
        org.dom4j.Document document = reader.read(inputStream);
        // 得到xml根元素
        org.dom4j.Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<org.dom4j.Element> elementList = root.elements();

        // 遍历所有子节点
        for (org.dom4j.Element e : elementList)
            map.put(e.getName(), e.getText());

        // 释放资源
        inputStream.close();
        inputStream = null;

        return map;
    }

    public static Map<String, Object> parseXml(HttpServletRequest request) throws Exception {
        // 解析结果存储在HashMap
        Map<String, Object> map = new HashMap<String, Object>();
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        org.dom4j.Document document = reader.read(inputStream);
        // 得到xml根元素
        org.dom4j.Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<org.dom4j.Element> elementList = root.elements();

        // 遍历所有子节点
        for (org.dom4j.Element e : elementList)
            map.put(e.getName(), e.getText());

        // 释放资源
        inputStream.close();
        inputStream = null;

        return map;
    }

}
